/*-
 * Shell.java
 *
 * $LastChangedBy:  $
 * $LastChangedRevision:  $
 * $LastChangedDate:  $
 * $HeadURL: $
 *
 * Copyright (c) 2007, Stein Gunnar Bakkeby
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Stein Gunnar Bakkeby nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.googlecode.attention.shell;

import java.util.ResourceBundle;

import com.googlecode.attention.shell.services.ShellServiceManager;
import com.googlecode.attention.util.ThreadTerminator;


/**
 * The shell, intended to be the root of the command line test application.
 *
 * @author Stein Gunnar Bakkeby
 */
public class Shell implements Runnable {

  private final ThreadTerminator<Shell> terminator;
  private final ResourceBundle resources;
  private static Shell shell;
  
  /**
   * Constructor, creates a default shell.
   */
  public Shell() {
    terminator = new ThreadTerminator<Shell>(this);
    resources = ResourceBundle.getBundle(
        "com/googlecode/attention/shell/language");
  }
  
  /**
   * Returns an instance of the global shell.
   * 
   * @return The shell
   */
  // Creating as singleton for now, as the quit command needs some way
  // of accessing the "shell", or at least the services
  public static Shell getInstance() {
    if (shell == null) shell = new Shell();
    return shell;
  }
  
  public void run() {
    startServices();
  }
  
  private void startServices() {
    // TODO: Note that it won't be possible to start, stop, and then start
    // services again with the thread terminator as it is now...
    ShellServiceManager.setThreadTerminator(terminator);
    ShellServiceManager.setResources(resources);
    final ShellServiceManager services = ShellServiceManager.getInstance();
    final Thread serviceThread = new Thread(services);
    serviceThread.start();
  }
  
  private void stopServices() {
    terminator.terminate();
  }
  
  /**
   * This will request the system to terminate.
   */
  public void quitRequest() {
    // for now just accept
    stopServices();
    try {
      Thread.sleep(2000);
    } catch (Exception e) {
      e.printStackTrace();
    }
    System.exit(0);
  }
  
  /**
   * The main method, creates an instance of the shell and starts it.
   * 
   * @param args Ignored
   */
  public static void main(String[] args) {
    Shell.getInstance().run();
  }
}